#include <iostream>
#include <sw/redis++/redis++.h>
#include <vector>
#include <string>
#include "PPrint.hpp"
#include <chrono>

using std::string;
using std::vector;

// get set
void test1(sw::redis::Redis &redis)
{
    std::cout << "get and set use way:" << std::endl;
    // first delete all keys
    try
    {
        redis.flushall();
        redis.set("key1", "111");
        redis.set("key2", "222");
        redis.set("key3", "333");
        // use get to attain keys value
        auto value1 = redis.get("key1");
        std::cout << "value1=" << value1.value() << std::endl;
        auto value4 = redis.get("key4");
        std::cout << "value4=" << value4.value() << std::endl;
    }
    catch (std::bad_optional_access &e)
    {
        std::cout << e.what() << std::endl;
    }
    std::cout << "hello,world" << std::endl;
}

void test2(sw::redis::Redis &redis)
{
    std::cout << "exists test" << std::endl;
    redis.flushall();

    redis.set("key1", "111");
    redis.set("key2", "222");
    auto ret = redis.exists("key1");
    std::cout << ret << std::endl;

    ret = redis.exists({"key1", "key2", "key3"});
    std::cout << ret << std::endl;
}

void test3(sw::redis::Redis &redis)
{
    std::cout << "del" << std::endl;
    redis.flushall();

    redis.set("key1", "111");
    redis.set("key2", "222");
    auto ret = redis.exists({"key1", "key2", "key3"});
    std::cout << ret << std::endl;

    ret = redis.del({"key1", "key2"});
    std::cout << ret << std::endl;

    ret = redis.exists({"key1", "key2", "key3"});
    std::cout << ret << std::endl;
}

void test4(sw::redis::Redis &redis)
{
    std::cout << "circulator keys" << std::endl;
    redis.flushall();

    redis.set("key1", "111");
    redis.set("key2", "222");
    redis.set("key3", "333");
    redis.set("key4", "444");
    redis.set("key5", "555");
    redis.set("key6", "666");

    // keys the second way to insert a iterator to install key
    // 接下来再创建一个插入迭代器指向容器的位置，就可以把 keys 获取到的结果依次通过刚才的插入迭代器插入到容器的指定位置中
    vector<string> result;
    auto it = std::back_inserter(result);
    redis.keys("*", it);
    printContainer(result);
}

void test5(sw::redis::Redis &redis)
{
    std::cout << "expire" << std::endl;
    redis.flushall();

    redis.set("key1", "111");
    redis.expire("key1", std::chrono::seconds(5));
    while (redis.exists("key1"))
    {
        printf("key1 exists! after %lld seconds expired\n", redis.ttl("key1"));
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    return;
}

void test6(sw::redis::Redis &redis)
{
    std::cout << "type" << std::endl;
    redis.flushall();

    redis.set("key1", "111");
    string result = redis.type("key1");
    std::cout << "key1:" << result << std::endl;

    redis.lpush("key2", "222");
    result = redis.type("key2");
    std::cout << "key2:" << result << std::endl;

    redis.hset("key3", "aaa", "111");
    result = redis.type("key3");
    std::cout << "key3:" << result << std::endl;

    redis.sadd("key5", "555");
    result = redis.type("key5");
    std::cout << "key5:" << result << std::endl;
}

int main()
{
    sw::redis::Redis redis("tcp://127.0.0.1:6379");
    // std::string result = redis.ping();
    // std::cout << result << std::endl;
    // test1(redis);
    test6(redis);
}